<template>
  <div>
    <el-tree
      ref="apiTree"
      v-model="apicheckedData"
      :data="apiListTow"
      :props="defaultProps"
      node-key="pm"
      show-checkbox
    />
  </div>
</template>

<script setup lang="ts">
import type { ApiGroup, ApiItem } from '../type';

import type { ApiInfo } from '#/api/sys/model/apiModel';
import type { ApiAuthorityItem } from '#/api/sys/model/authority';

import { $t } from '@vben/locales';

import { getApiList } from '#/api/sys/api';
import { arrayGroupBy } from '#/utils/arraygroup';

const defaultProps = {
  children: 'children',
  label: 'description',
};

const apiTreeRef = useTemplateRef('apiTree');
const apicheckedData = defineModel<ApiAuthorityItem[]>('apicheckedData'); // 选择状态数组
const apiList = ref<ApiGroup[]>([]); // 按group分组后的数据
const apiListTow = ref<ApiGroup[]>([]); // 按serviceName分组后的三层树形结构数据
// 获取接口列表数据
const getApiListData = async () => {
  // eslint-disable-next-line no-async-promise-executor
  return new Promise(async (resolve, reject) => {
    try {
      const { data } = await getApiList({ page: 1, pageSize: 10_000 }); // 调用实际的 API 获取数据
      data.forEach((item: ApiInfo) => {
        return (item.description = $t(`sys.${item.description}`));
      }); // 处理第一层国际化
      const apisMapList = arrayGroupBy(data, (item) => item.group); // 根据group属性分组

      // 构建二层树形
      for (const item of apisMapList.keys()) {
        apiList.value.push({
          description: $t(`sys.${item}`),
          children: apisMapList.get(item),
        });
      }

      // 构建三层树形解构
      buildApiTree(apiList.value);
      resolve('成功');
    } catch {
      // eslint-disable-next-line prefer-promise-reject-errors
      reject('失败');
    }
  });
};

/**
 * @author Buke
 * @description 构建三层次树形结构
 * @param {ApiGroup[]} apiList - 接口列表数据。
 * @returns {void}
 */
function buildApiTree(apiList: ApiGroup[]): void {
  const apiMap = new Map();
  for (const item of apiList) {
    // 存在children属性时，遍历children属性
    for (const child of item.children!) {
      if (!apiMap.has(child.serviceName)) {
        apiMap.set(child?.serviceName, []);
      }
      // 检查数组内是否存在一样的数据
      const flag = apiMap
        .get(child.serviceName)
        .some((K: ApiItem) => K.description === item.description);
      if (!flag) {
        apiMap.get(child.serviceName)?.push(item);
      }
    }
  }
  // 重构成树形解构
  for (const item of apiMap.keys()) {
    apiListTow.value.push({
      description: $t(`sys.${item}`),
      children: apiMap.get(item),
    });
  }
}

// 获取选择树节点的数据
const getApiTreeNodes = async () => {
  const arr: ApiAuthorityItem[] =
    apiTreeRef.value?.getCheckedNodes() as ApiAuthorityItem[];

  // 数据过滤
  const data = arr
    ?.map((item: ApiAuthorityItem) => ({
      path: item.path,
      method: item.method,
      pm: item.pm,
    }))
    .filter((item: ApiAuthorityItem) => item.path !== undefined);
  return data;
};

watch(
  () => apicheckedData.value,
  async (val: any) => {
    // if (val && Array.isArray(val) && val.length > 0) {
    // 等待树结构建完成
    await getApiListData();
    // 设置节点选择状态
    await nextTick(() => {
      apiTreeRef.value?.setCheckedNodes(val);
    });
  },
  // },
);
defineExpose({
  getApiTreeNodes, // 导出选择的节点数据
});
</script>
